package com.stars.easyms.base.boot;

import com.stars.easyms.base.util.ConfigurationPropertiesUtil;
import com.stars.easyms.base.util.ReflectUtil;
import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Set;

/**
 * <p>className: EasyMsConfigurationPropertiesBeansRegisterRunner</p>
 * <p>description: EasyMs配置属性bean自动注册到可rebind列表中，允许nacos等配置中心修改后自动刷新</p>
 *
 * @author guoguifang
 * @version 1.7.2
 * @date 2021/1/6 11:58 上午
 */
public class EasyMsConfigurationPropertiesBeansRegisterRunner implements ApplicationRunner, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) {
        // 拿到所有增加了@ConfigurationProperties注解的属性bean类
        Set<Class<?>> allClassByAnnotation = ReflectUtil.getAllClassByAnnotation(ConfigurationProperties.class);
        if (allClassByAnnotation.isEmpty()) {
            return;
        }

        ConfigurationPropertiesBeans configurationPropertiesBeans =
                this.applicationContext.getBean(ConfigurationPropertiesBeans.class);
        Set<String> currPropertiesBeanNames = configurationPropertiesBeans.getBeanNames();
        for (Class<?> clazz : allClassByAnnotation) {
            String propertiesName = ConfigurationPropertiesUtil.getName(clazz);
            if (!currPropertiesBeanNames.contains(propertiesName)) {
                try {
                    configurationPropertiesBeans.postProcessBeforeInitialization(
                            this.applicationContext.getBean(propertiesName), propertiesName);
                } catch (BeansException e) {
                    // ignore
                }
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
